import GraphBase from "./graphBase";
export default class EllipseNodeGraph extends GraphBase {
  center: {
    x: number;
    y: number;
  } = { x: 0, y: 0 };
  radius: {
    x: number;
    y: number;
  } = { x: 0, y: 0 };
  background: string = "rgb(64,158,255)";
  isFill = true;
  type = "ellipse";
  private originRect = { x: 0, y: 0, width: 0, height: 0 };
  constructor() {
    super();
  }
  draw() {
    if (!this.ctx) {
      return;
    }
    this.ctx.beginPath();
    this.ctx.ellipse(
      this.center.x,
      this.center.y,
      Math.abs(this.radius.x),
      Math.abs(this.radius.y),
      this.rotation,
      0,
      Math.PI * 2
    );
    if (this.isFill) {
      this.ctx.fillStyle = this.background;
      this.ctx.fill();
    } else {
      this.ctx.stroke();
    }
  }
  contain(x: number, y: number): boolean {
    const _x = x - this.center.x;
    const _y = y - this.center.y;
    if (this.isFill) {
      const c =
        (_x * _x) / (this.radius.x * this.radius.x) +
        (_y * _y) / (this.radius.y * this.radius.y);
      return c <= 1;
    } else {
      const c =
        (_x * _x) / (this.radius.x * this.radius.x) +
        (_y * _y) / (this.radius.y * this.radius.y);
      const cabs = Math.abs(c - 1);
      return cabs <= 0.01;
    }
  }
  setOriginRect(x: number, y: number, width: number, height: number) {
    this.originRect.x = x;
    this.originRect.y = y;
    this.originRect.width = width;
    this.originRect.height = height;
  }
  getOriginRect() {
    return {
      x: this.originRect.x,
      y: this.originRect.y,
      width: this.originRect.width,
      height: this.originRect.height,
    };
  }
  setRadiusX(x: number) {
    this.radius.x = x;
  }
  setRadiusY(y: number) {
    this.radius.y = y;
  }
  setPosition(x: number, y: number) {
    this.center.x = x;
    this.center.y = y;
  }
  setRotation(rotation: number) {
    this.rotation = rotation;
  }
  setBackgroundColor(color: string) {
    this.background = color;
  }
  getRect(): {
    x: number;
    y: number;
    width: number;
    height: number;
  } {
    return {
      x: this.center.x - this.radius.x,
      y: this.center.y - this.radius.y,
      width: 2 * this.radius.x,
      height: 2 * this.radius.y,
    };
  }
  translate(x: number, y: number) {
    const originRect = this.getOriginRect();
    this.center.x = originRect.x + originRect.width / 2 + x;
    this.center.y = originRect.y + originRect.height / 2 + y;
  }
  offset(x: number, y: number) {
    this.center.x = this.center.x + x;
    this.center.y = this.center.y + y;
  }
  scale(x: number, y: number) {
    this.setRadiusX(this.radius.x * x);
    this.setRadiusY(this.radius.y * y);
  }
  changeProperty(propertyName: string, propertyValue: any) {
    switch (propertyName) {
      case "radiusx":
        this.radius.x = propertyValue;
        break;
      case "radiusy":
        this.radius.y = propertyValue;
        break;
      case "background":
        this[propertyName] = propertyValue;
        break;
      case "isFill":
        this[propertyName] = propertyValue;
        break;
      case "x":
        this.setPosition(propertyValue, this.center.y);
        let rect = this.getRect();
        this.setOriginRect(rect.x, rect.y, rect.width, rect.height);
        break;
      case "y":
        this.setPosition(this.center.x, propertyValue);
        let rect1 = this.getRect();
        this.setOriginRect(rect1.x, rect1.y, rect1.width, rect1.height);
        break;
      default:
        break;
    }
  }
  setZoom(zoom: number = 1) {
    this.zoom = zoom;
    this.setRadiusX(this.radius.x * zoom);
    this.setRadiusY(this.radius.y * zoom);
    this.setPosition(this.center.x * zoom, this.center.y * zoom);
    const newRect = this.getRect();
    this.setOriginRect(newRect.x, newRect.y, newRect.width, newRect.height);
  }
  getZoom(): number {
    return this.zoom;
  }
}
